Prezentacja Adaptive Cards
Table of Contents
Ten post jest związany z screencastem, który niedawno zrobiłem. Opisuje w szczegółach, w jaki sposób Flow, używany przez to rozwiązanie, jest zbudowany. Życzę przyjemnego oglądania i nauki jednocześnie, jak takie rozwiązanie można wykonać. Ten wpis jest również częścią serii, którą piszę o „Adaptive Cards”.
Screencast
Rozwiązanie
Rozwiązanie jest zbudowane przy użyciu PowerApps, dając użytkownikom interfejs dla procesu. Wszystkie dane są przechowywane w dwóch encjach, w Common Data Service (CDS). Rozwiązanie korzysta również z Microsoft Teams wraz z Adaptive Cards, jako medium do komunikacji w podejściu Digital Workplace (wszystkie informacje przechowywane w jednym środowisku, zunifikowany user experience) i Microsoft Flow, który obsługuje zatwierdzanie i przetwarzanie danych.
W tym poście skoncentruję się tylko na Microsoft Flow i sposobie jego działania z kartami Adaptive Cards, ponieważ stanowi on rdzeń całego rozwiązania.
Jak został zbudowany Flow
Ponieważ aplikacja, jaką zbudowałem, posiada poziom obsługi błędów wyłapujący błędy na poziomie danych, toteż uznałem, że nie ma powodu by po wysłaniu nowego wniosku aplikacja czekała, aż Flow zostanie wykonany. Z tego powodu zdecydowałem się na użycie innego wyzwalacza:zamiast PowerApps użyłem wyzwalacza „When a record is created” (1) z zestawu wyzwalaczy usługi Common Data Service (pamiętaj, że wymaga on licencji P1!).
Dalej (2) pobieram informację o powiązanym rekordzie, który zawiera limity dostępnych dni dla użytkownika, który uruchomił Flow, dla bieżącego roku. W tym celu używam kolumny „lookup” w CDS, budując relację między pojedynczym żądaniem, a informacjami o limitach użytkownika:
Następnym krokiem (3) jest uzyskanie szczegółów wnioskującego i danych menedżera. Wykonuję to za pomocą działań z zestawu akcji „Office 365 Users”:
- Get user profile (V2)
- Get manager (V2)
Przygotowywanie i przydzielanie zadania
Teraz zaczyna się magia 🙂 W scope (4) Flow wykonuje następujące czynności:
(A) Przypisuję zadanie do menedżera, używając akcji „Create an approval (V2)”. Akcja tworzy zadanie dla osoby zatwierdzającej, ale nie wstrzymuje przepływu pracy do czasu jego zakończenia. Po prostu przypisuje zadanie i przechodzi dalej.
(B) Jednym z atrybutów zwracanych z akcji zadania jest kod JSON „Adaptive Card”. W pełni działający! Następnie parsuję go, aby móc pobrać z niego każdą właściwość, którą chcę:
Chciałem jednak zmienić jego wygląd i zastąpić go własnym:
Ważne! Adaptive Card generowana przez Flow ma właściwość „Actions”, która zawiera definicję przycisków „Approve” i „Reject”. Zawiera ona także wiele wartości wymaganych przez Flow Bot, aby poprawnie przeanalizować żądanie i zakończyć powiązane zadanie:
Mając to na uwadze, postanowiłem nie budować całkowicie własnej karty Adaptive Card, ale po prostu przygotować i użyć jej właściwości „Body”. Po przygotowaniu kodu wkleiłem go do akcji „Compose” (C) w Flow i zastąpiłem wartości właściwościami z przepływu, a na koniec zbudowałem nowy kod karty Adaptive Card łącząc informacje nagłówka oryginalnej karty ze spersonalizowaną treścią i akcjamm z oryginalnej karty (D):
substring(body('Assign_approval_task_to_manager')?['adaptiveCard'], 0, indexOf(body('Assign_approval_task_to_manager')?['adaptiveCard'], '"body"'))
Aby uzyskać nagłówek, a więc wszystkie informacje przed strukturą „body”.outputs('New_Body_part_of_card')
Mój nowy kod „Body”.substring(body('Assign_approval_task_to_manager')?['adaptiveCard'], indexOf(body('Assign_approval_task_to_manager')?['adaptiveCard'], '"actions"'), sub(length(body('Assign_approval_task_to_manager')?['adaptiveCard']), indexOf(body('Assign_approval_task_to_manager')?['adaptiveCard'], '"actions"')))
Aby uzyskać „Actions”, a więc wszystkie informacje po strukturze „Body”.
Tak przygotowany kod jest wysyłany za pomocą akcji „Post your own adaptive card as the Flow bot to a user (Preview)” do osoby zatwierdzającej (E).
Następne (5) przepływ zostaje wstrzymany w oczekiwaniu na zakończenie zadania. Po zatwierdzeniu zadania (za pomocą Adaptive Card w Teams lub przycisków w wiadomości e-mail, lub aplikacji mobilnej Flow) przepływ może przejść dalej. Następnie inicjuję zmienną, aby przechowywać komentarze zatwierdzenia (6). Ponieważ nie jest to pole wymagane w zadaniu, jest możliwe, że będzie puste. To z kolei sprawiało, że Flow się kończył błędem, kiedy następowała próba zapisania tej null-owej informacji w polu „Approval Comments” w CDS. Dlatego zdecydowałem się użyć opcji „Run after” w akcji „Set variable” i połączyć komentarz z pustym stringiem, co rozwiązało problem: (concat(outputs('Get_approval_comments'), '')
):
Obsługa wyniku zatwierdzania
I tu zaczyna się finalny scope (7):
Najpierw aktualizuje (A) rekord wniosku w encji CDS przechowującej informacje o zatwierdzeniu: kto, kiedy, jaki jest wynik i komentarz. Następnie (B), w oparciu o wynik, wysyła kolejną kartę Adaptive Card do wnioskującego z informacją o akceptacji lub odrzuceniem wniosku:
Używając poniższych kart:
Następnie (C) dodaje wpis do kalendarza wnioskującego i managera na okres urlopu. Następnie generuje plik ICS, wykorzystując dane z przepływu i używając właściwego dla tego rodzaju pliku formatu. Wreszcie zapisuje plik w Aure Blob Storage:
Ważne! Jeśli chcesz, aby Twój plik ICS został pobrany podczas wywoływania jego adresu URL, a nie wyświetlany w przeglądarce jako zwykły tekst, użyj „application/octet-stream
” jako content type.
Wreszcie (E) aktualizuje limit dni pozostałych dla użytkownika i wysyła kartę Adaptive Card do kanału w Microsoft Teams, aby inni członkowie zespołu dowiedzieli się, kiedy ich kolega będzie nieobecny. Umożliwia także im pobranie wygenerowanego wcześniej pliku ICS, aby dodać ten fakt do ich kalendarzy:
I to wszystko! Mam nadzieje ze Ci się podobało.
Jeśli masz jakieś pytania lub chciałbyś, abym Ci pomógł w Twojej podróży z Adaptive Cards, zostaw komentarz lub skontaktuj się ze mną za pomocą formularza kontaktowego.